package com.xdcplus.web.service.alarm.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.xdcplus.core.utils.BeanUtils;
import com.xdcplus.exceptions.XdcWebException;
import com.xdcplus.mom.constants.NumberConstant;
import com.xdcplus.mom.enums.ResponseEnum;
import com.xdcplus.mp.service.impl.BaseServiceImpl;
import com.xdcplus.mp.utils.PageableUtils;
import com.xdcplus.mp.utils.PropertyUtils;
import com.xdcplus.pager.vo.PageVO;
import com.xdcplus.web.common.pojo.dto.TreeDto;
import com.xdcplus.web.common.pojo.dto.alarm.ToolAlarmGroupDTO;
import com.xdcplus.web.common.pojo.dto.alarm.ToolAlarmGroupFilterDTO;
import com.xdcplus.web.common.pojo.dto.alarm.ToolAlarmGroupUpdateDTO;
import com.xdcplus.web.common.pojo.entity.alarm.ToolAlarmCode;
import com.xdcplus.web.common.pojo.entity.alarm.ToolAlarmGroup;
import com.xdcplus.web.common.pojo.query.alarm.ToolAlarmGroupQuery;
import com.xdcplus.web.common.pojo.vo.alarm.ToolAlarmGroupVO;
import com.xdcplus.web.mapper.alarm.ToolAlarmGroupMapper;
import com.xdcplus.web.service.alarm.ToolAlarmCodeService;
import com.xdcplus.web.service.alarm.ToolAlarmGroupService;
import com.xdcplus.web.service.alarm.ToolAlarmGroupToolService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 设备告警组表(ToolAlarmGroup)表服务实现类
 *
 * @author bullion.yan
 * @since 2024-06-05 16:16:14
 */
@Slf4j
@Service("toolAlarmGroupService")
public class ToolAlarmGroupServiceImpl extends BaseServiceImpl<ToolAlarmGroupMapper, ToolAlarmGroup, ToolAlarmGroup, ToolAlarmGroupVO> implements ToolAlarmGroupService {

    @Autowired
    protected ToolAlarmGroupMapper toolAlarmGroupMapper;
    @Autowired
    private ToolAlarmCodeService toolAlarmCodeService;
    @Autowired
    private ToolAlarmGroupToolService toolAlarmGroupToolService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean saveToolAlarmGroup(ToolAlarmGroupDTO toolAlarmGroupDTO) {
        ToolAlarmGroup toolAlarmGroup = new ToolAlarmGroup();
        BeanUtil.copyProperties(toolAlarmGroupDTO, toolAlarmGroup);
        toolAlarmGroup.setCreatedTime(new Timestamp(DateUtil.current()));
        validateToolGroupNameIsExist(toolAlarmGroup);
        return this.save(toolAlarmGroup);
    }

    private  void validateToolGroupNameIsExist(ToolAlarmGroup toolAlarmGroup){
        ToolAlarmGroup toolAlarmGroupExists=  toolAlarmGroupMapper.queryByToolGroupCode(toolAlarmGroup.getToolGroupCode());
        if(toolAlarmGroupExists!=null && (!toolAlarmGroupExists.getId().equals(toolAlarmGroup.getId()))){
            throw new XdcWebException(ResponseEnum.ERROR,String.format("设备组编号:[%s]已经存在",toolAlarmGroup.getToolGroupCode()));
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean updateToolAlarmGroup(ToolAlarmGroupUpdateDTO toolAlarmGroupUpdateDTO) {
        ToolAlarmGroup toolAlarmGroup = this.getById(toolAlarmGroupUpdateDTO.getId());
        if (ObjectUtil.isNull(toolAlarmGroup)) {
            log.error("updateToolAlarmGroup() The ToolAlarmGroup does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        toolAlarmGroup.setToolGroupName(toolAlarmGroupUpdateDTO.getToolGroupName());
        toolAlarmGroup.setUpdatedUser(toolAlarmGroupUpdateDTO.getUpdatedUser());
        toolAlarmGroup.setUpdatedTime(new Timestamp(DateUtil.current()));
        return this.updateById(toolAlarmGroup);
    }

    @Override
    public Boolean saveOrUpdateBatch(List<ToolAlarmGroup> toolAlarmGroupList) {
        toolAlarmGroupList.forEach(toolAlarmGroup -> {
            ToolAlarmGroup toolAlarmGroupParam = new ToolAlarmGroup();
            toolAlarmGroupParam.setId(toolAlarmGroup.getId());
            if (ObjectUtil.isNotNull(toolAlarmGroup.getId())) {
                toolAlarmGroup.setId(toolAlarmGroup.getId());
                toolAlarmGroup.setUpdatedTime(new Timestamp(DateUtil.current()));
                LambdaUpdateWrapper<ToolAlarmGroup> lambdaUpdate = Wrappers.lambdaUpdate();
                lambdaUpdate.eq(ToolAlarmGroup::getId, toolAlarmGroup.getId());
                update(toolAlarmGroup, lambdaUpdate);
            } else {
                toolAlarmGroup.setCreatedTime(new Timestamp(DateUtil.current()));
                save(toolAlarmGroup);
            }
        });
        return true;
    }

    @Override
    public Boolean saveOrUpdateBatchByDTOList(List<ToolAlarmGroupDTO> toolAlarmGroupDTOList) {
        List<ToolAlarmGroup> toolAlarmGroupList = BeanUtils.copyProperties(toolAlarmGroupDTOList, ToolAlarmGroup.class);
        return saveOrUpdateBatch(toolAlarmGroupList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteToolAlarmGroupLogical(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        ToolAlarmGroup toolAlarmGroup = this.getById(id);

        if (ObjectUtil.isNull(toolAlarmGroup)) {
            log.error("deleteToolAlarmGroup() The ToolAlarmGroup does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        //分类有子级无法删除
        List<ToolAlarmGroup>  toolAlarmGroupList=toolAlarmGroupMapper.queryByParentId(id);
        if(CollUtil.isNotEmpty(toolAlarmGroupList)){
            throw new XdcWebException(ResponseEnum.ERROR,"设备组含有子级，无法删除");
        }
        //分类有绑定的项目，无法删除。
        List<ToolAlarmCode> toolAlarmCodeList=toolAlarmCodeService.queryByGroupIdFk(id);
        if(CollUtil.isNotEmpty(toolAlarmCodeList)){
            throw new XdcWebException(ResponseEnum.ERROR,"设备组含有绑定的告警代码，无法删除");
        }
        //删除分类绑定的设备
        toolAlarmGroupToolService.deleteByGroupIdFk(id);
        return this.removeById(id);
    }

    private List<ToolAlarmGroup> queryToolAlarmGroupList(ToolAlarmGroupFilterDTO toolAlarmGroupFilterDTO) {
        ToolAlarmGroupQuery toolAlarmGroupQuery = BeanUtil.copyProperties(toolAlarmGroupFilterDTO, ToolAlarmGroupQuery.class);

        return toolAlarmGroupMapper.queryToolAlarmGroup(toolAlarmGroupQuery);
    }

    @Override
    public List<ToolAlarmGroupVO> queryToolAlarmGroupVOList(ToolAlarmGroupFilterDTO toolAlarmGroupFilterDTO) {
        return this.objectConversion(queryToolAlarmGroupList(toolAlarmGroupFilterDTO));
    }

    @Override
    public PageVO<ToolAlarmGroupVO> queryToolAlarmGroup(ToolAlarmGroupFilterDTO toolAlarmGroupFilterDTO) {
        PageVO<ToolAlarmGroupVO> pageVO = new PageVO<>();

        if (toolAlarmGroupFilterDTO.getCurrentPage() > NumberConstant.ZERO) {
            PageableUtils.basicPage(toolAlarmGroupFilterDTO.getCurrentPage(), toolAlarmGroupFilterDTO.getPageSize(),
                    toolAlarmGroupFilterDTO.getOrderType(), toolAlarmGroupFilterDTO.getOrderField());
        }

        List<ToolAlarmGroup> toolAlarmGroupList = queryToolAlarmGroupList(toolAlarmGroupFilterDTO);

        PageInfo<ToolAlarmGroup> pageInfo = new PageInfo<>(toolAlarmGroupList);
        PropertyUtils.copyProperties(pageInfo, pageVO, this.objectConversion(toolAlarmGroupList));

        return pageVO;
    }

    @Override
    public ToolAlarmGroupVO queryToolAlarmGroupById(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        return this.objectConversion(this.getById(id));
    }

    @Override
    public List<TreeDto<ToolAlarmGroup>> findToolAlarmGroupTree() {
        ToolAlarmGroupQuery toolAlarmGroupQuery=new ToolAlarmGroupQuery();
        List<ToolAlarmGroup>   toolAlarmGroupList = toolAlarmGroupMapper.queryToolAlarmGroup(toolAlarmGroupQuery);
        if (CollectionUtil.isNotEmpty(toolAlarmGroupList)) {
            List<TreeDto<ToolAlarmGroup>> bisFormTree = toolAlarmGroupList.stream().map(bisForm -> {
                TreeDto<ToolAlarmGroup> fromTreeDto = new TreeDto<ToolAlarmGroup>();
                fromTreeDto.setId(bisForm.getId());
                fromTreeDto.setData(bisForm);
                fromTreeDto.setParentId(bisForm.getParentId());
                fromTreeDto.setName(bisForm.getToolGroupName());
                fromTreeDto.setType(bisForm.getGroupType());
                return fromTreeDto;
            }).collect(Collectors.toList());
            return streamToTree(bisFormTree, 0L);
        } else {
            return new ArrayList<>();
        }
    }

    public static List<TreeDto<ToolAlarmGroup>> streamToTree(List<TreeDto<ToolAlarmGroup>> treeList, Long parentId) {
        List<TreeDto<ToolAlarmGroup>> list = treeList.stream()
                // 过滤父节点
                .filter(parent -> parent.getParentId().equals(parentId))
                // 把父节点children递归赋值成为子节点
                .map(child -> {
                    List<TreeDto<ToolAlarmGroup>> subList = streamToTree(treeList, child.getId());
                    child.setSubDataList(subList);
                    return child;
                }).collect(Collectors.toList());
        return list;
    }
}
